fix: render assistant text bubble for messages with tool calls#3315
fix: render assistant text bubble for messages with tool calls#3315xingzhiyyu wants to merge 5 commits into
Conversation
AI messages with both tool_calls and text content were previously missing a visible assistant bubble — the text was hidden inside the Chain of Thought processing panel. Insert an assistant group before the processing group so the reply text renders as a normal chat bubble while lastOpenGroup() continues to work for subsequent tool results.
There was a problem hiding this comment.
Pull request overview
This PR fixes frontend message grouping so AI messages with both visible text and tool calls can render assistant text while preserving processing/tool-call grouping.
Changes:
- Updates
getMessageGroups()to create assistant bubbles for AI messages with content even when they also require processing. - Inserts the visible assistant bubble before the processing group so later tool messages still attach correctly.
- Adds regression tests for tool calls with text, reasoning with tool calls and text, and plain text responses.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
frontend/src/core/messages/utils.ts |
Adjusts AI message grouping logic for content plus tool calls/reasoning. |
frontend/tests/unit/core/messages/utils-regression.test.ts |
Adds regression coverage for assistant text visibility around tool calls. |
| if (hasSubagent(message)) { | ||
| groups.push({ | ||
| id: message.id, | ||
| type: "assistant:subagent", | ||
| messages: [message], | ||
| }); | ||
| } else if (hasReasoning(message) || hasToolCalls(message)) { | ||
| continue; |
There was a problem hiding this comment.
@copilot Simply answer me in Chinese,can the issue be resolved by placing this branch after the "needprocessing" branch? Don‘t make any chance to the code.
- Move hasSubagent check before needsProcessing so subagent messages get an assistant bubble for visible content + subagent group for tool results, avoiding a dangling processing group - Apply same pattern to hasPresentFiles: assistant bubble for text + present-files group for the file panel - Update regression tests to match new expected ordering
|
我尝试改了copilot提到的问题,现在因为present file 的分支在渲染的时候同时渲染ai生成的正文的file,所以不用做其他处理直接用一个message push上去就能显示,subagent的部分生成一个正常的assistant和一个assistant:subagent,如果没理解错的话在前端这两类一个只渲染正文,另一个渲染subagent消息,同一条消息push两种就能让正文和subagent一起显示,解决了subagent消息里正文被吞的问题,但现在这种方案导致这方面的token计量可能会被高估 |
Fixes #3251
Why
In the previous version, an AI message containing both text content and tool calls would be hidden from the normal assistant message stream. It would not be rendered directly to the user as a regular text bubble, and would instead only appear in the TOOL-CALLS panel or the Chain of Thought section.
This behavior does not match our expected UI behavior.
This PR ensures that assistant messages with text content are shown in the normal message stream, while Chain of Thought and tool calls continue to be displayed only in their respective panels.
What changed
Messages with both tool_calls and text content now produce two groups: an assistant bubble (renders the reply text) and an assistant:processing group (handles the tool call chain). Previously only the processing group was created, leaving the text trapped inside the Chain of Thought panel.
The bubble is spliced before the processing group rather than pushed to the end. This keeps lastOpenGroup() working correctly — subsequent tool results still land in the processing group.
Also added a regression test covering: tool calls + text, reasoning + tool calls + text, and plain text (no tool calls).
Surface area
frontend/backend/applanggraph.json, or prompt changedocker/or sandboxed executionskills/backend/pyproject.tomlorfrontend/package.json(say what it buys us)Screenshots / Recording
Bug fix verification
Validation
Test Files 24 passed (24)
Tests 163 passed (163)
Start at 15:35:28
Duration 592ms (transform 764ms, setup 0ms, import 1.60s, tests 298ms, environment 1ms)
I recloned the repository from my fork that I used to submit this PR, then ran cd frontend && pnpm format && pnpm lint && pnpm typecheck && BETTER_AUTH_SECRET=local-dev-secret pnpm build && make test. All checks passed.